/*
 * gx_log.h
 *
 *  Created on: 2012-4-1
 *      Author: zhanggx
 *
 *  only a global log exists in the whole gxdht
 */

#ifndef GX_LOG_H_
#define GX_LOG_H_
#include <pthread.h>

#include "gx.h"

#define GX_LOG_TRACE 	0
#define GX_LOG_DEBUG 	1
#define GX_LOG_NOTICE 	2
#define GX_LOG_WARNING  3
#define GX_LOG_ERROR 	4


#define __gx_v_line(x) #x
#define __gx_line(x) __gx_v_line(x)
#define GX_LOG_WITH_FL(level, fmt, arg...) do{ 			\
		gx_log(level, "[" __FILE__ "]"					\
					  " [" __gx_line(__LINE__) "]:" fmt "\n", ##arg);\
	}while(0)


#define GX_TRACE_LOG(fmt, arg...) 	GX_LOG_WITH_FL(GX_LOG_TRACE, 	fmt, ##arg)
#define GX_DEBUG_LOG(fmt, arg...) 	GX_LOG_WITH_FL(GX_LOG_DEBUG, 	fmt, ##arg)
#define GX_NOTICE_LOG(fmt, arg...) 	GX_LOG_WITH_FL(GX_LOG_NOTICE,	fmt, ##arg)
#define GX_WARNING_LOG(fmt, arg...) GX_LOG_WITH_FL(GX_LOG_WARNING,	fmt, ##arg)
#define GX_ERROR_LOG(fmt, arg...) 	GX_LOG_WITH_FL(GX_LOG_ERROR,	fmt, ##arg)

#ifdef GX_ENABLE_ANSI_COLOR
	#define GX_ANSI_ESC "\033"
	#define GX_CSI			GX_ANSI_ESC "["
	#define GX_ANSI_BLACK 	GX_CSI "30m" 	/* 黑色 */
	#define GX_ANSI_RED	  	GX_CSI "31m" /* 红色 */
	#define GX_ANSI_GREEN 	GX_CSI "32m" /* 绿色 */
	#define GX_ANSI_YELLOW 	GX_CSI "33m" 	/* 黄色 */
	#define GX_ANSI_BLUE	GX_CSI "34m" /* 蓝色 */
	#define GX_ANSI_MAGINA	GX_CSI "35m" /* 紫色 */
	#define GX_ANSI_CYAN	GX_CSI "36m" 	/* 青色 */
	#define GX_ANSI_WHITE	GX_CSI "37m" 	/* 白色 */

	/* 加强前景色 */

	#define GX_ANSI_FGRED 		GX_CSI "1;31m" /* 亮红 */
	#define GX_ANSI_FGGREEN 	GX_CSI "1;32m" /* 亮绿 */
	#define GX_ANSI_FGYELLO 	GX_CSI "1;33m" /* 亮黄 */
	#define GX_ANSI_FGBLACK 	GX_CSI "1;34m" /* 亮蓝 */
	#define GX_ANSI_FGMAGINA 	GX_CSI "1;35m" /* 亮紫 */
	#define GX_ANSI_FGCYAN 		GX_CSI "1;36m" /* 亮青 */
	#define GX_ANSI_FGWHITE 	GX_CSI "1;37m" /* 亮白 */


	#define GX_ANSI_BGRED 		GX_CSI "41;1m" /* 亮红 */
	#define GX_ANSI_BGGREEN 	GX_CSI "42;1m" /* 亮绿 */
	#define GX_ANSI_BGYELLO 	GX_CSI "43;1m" /* 亮黄 */
	#define GX_ANSI_BGBLUE		GX_CSI "44;1m" /* 亮蓝 */
	#define GX_ANSI_BGMAGINA 	GX_CSI "45;1m" /* 亮紫 */
	#define GX_ANSI_BGCYAN 		GX_CSI "46;1m" /* 亮青 */
	#define GX_ANSI_BGWHITE 	GX_CSI "47;1m" /* 亮白 */


	#define GX_ANSI_OBGBLACK 	GX_CSI "40m" /*黑色 */
	#define GX_ANSI_OBGRED 		GX_CSI "41m" /*红色 */
	#define GX_ANSI_OBGREEN 	GX_CSI "42m" /*绿色 */
	#define GX_ANSI_OBYELLO 	GX_ACSI "43m" /* 黄色 */
	#define GX_ANSI_OBGBLUE 	GX_CSI "44m" /*蓝色 */
	#define GX_ANSI_OBGMAGINA 	GX_CSI "45m" /*紫色 */
	#define GX_ANSI_OBGCYAN 	GX_CSI "46m" /*青色 */

	#define GX_ANSI_CLRALL 		GX_CSI "2;37;0m" /* 返回原色 */

	#define GX_LOG_WITH_FL_AND_COLOR(level, fmt, arg...) 		do{ 			\
		gx_log(level,  "[" GX_ANSI_GREEN __FILE__ GX_ANSI_CLRALL "]" 					\
					  " [" GX_ANSI_YELLOW __gx_line(__LINE__) GX_ANSI_CLRALL "]:" fmt, ##arg);\
	}while(0)
#else
	#define GX_LOG_WITH_FL_AND_COLOR(level, fmt, arg...) GX_LOG_WITH_FL(level, fmt, ##arg);
#endif

#define GX_TRACE_COLORLOG(fmt, arg...) 	GX_LOG_WITH_FL_AND_COLOR(GX_LOG_TRACE, 	fmt, ##arg)
#define GX_DEBUG_COLORLOG(fmt, arg...) 	GX_LOG_WITH_FL_AND_COLOR(GX_LOG_DEBUG, 	fmt, ##arg)
#define GX_NOTICE_COLORLOG(fmt, arg...) 	GX_LOG_WITH_FL_AND_COLOR(GX_LOG_NOTICE,	fmt, ##arg)
#define GX_WARNING_COLORLOG(fmt, arg...) GX_LOG_WITH_FL_AND_COLOR(GX_LOG_WARNING,	fmt, ##arg)
#define GX_ERROR_COLORLOG(fmt, arg...) 	GX_LOG_WITH_FL_AND_COLORL(GX_LOG_ERROR,	fmt, ##arg)
struct gx_log_s {
	int filefd;
	FILE* f_fp;
	const char* log_path;
	int log_level;
	int enable_color_log;

	int notify_fd;

	pthread_mutex_t mutex;

	void (*on_log_changed)(void);
};

int gx_set_log_file(const char* path);
void gx_set_log_level(int level);
void gx_log(int log_level, const char* fmt,...);
#endif /* GX_LOG_H_ */
